<?php

namespace App\Http\Controllers\Admin\System;

use App\Enums\ResponseEnum;
use App\Http\Controllers\AdminController;
use App\Models\System\Menus;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\System\Role;

class RoleController extends AdminController
{
    public function data(Request $request)
    {
        $model = Role::query()->select(['id', 'name', 'created_at', 'updated_at'])->where('guard_name', static::GUARD_NAME);
        if ($keywords = $request->get('keywords')) {
            $model->where('name', 'like', $keywords . '%');
        }
        if ($request->get('isAll')) {
            $list = $model->get()->toArray();
            return $this->succeed($this->disposeData($list));
        }
        $total = $model->count();
        $page = (int)$request->get('page', 1);
        $pageSize = (int)$request->get('pageSize', 10);
        $list = $model->offset(($page - 1) * $pageSize)->limit($pageSize)->get()->toArray();
        return $this->succeed([
            "total" => $total,
            "rows" => $this->disposeData($list)
        ]);
    }

    private function disposeData($list)
    {
        if (!empty($list)) {
            foreach ($list as $key => $value) {
                $list[$key]['created_at'] = Carbon::parse($value['created_at'])->format('Y-m-d H:i:s');
                $list[$key]['updated_at'] = Carbon::parse($value['updated_at'])->format('Y-m-d H:i:s');
            }
        }
        return $list;
    }

    public function store(Request $request)
    {
        $request->validate([
            'name' => ['required','max:30','unique:roles'],
        ]);
        $data = $request->only(['name']);
        DB::beginTransaction();
        try {
            $model = Role::query()->create(['name' => $data['name'], 'guard_name' => static::GUARD_NAME]);
            $this->createSyslog('添加了一条角色记录', $data, $model);
            DB::commit();
            return $this->succeed([
                'id' => $model['id'],
                'created_at' => Carbon::parse($model['created_at'])->format('Y-m-d H:i:s'),
                'updated_at' => Carbon::parse($model['updated_at'])->format('Y-m-d H:i:s'),
            ]);
        }catch (\Exception $e) {
            DB::rollBack();
        }
        return $this->fail();
    }

    public function update(Request $request, $id)
    {
        $request->validate([
            'name' => ['required','max:30','unique:roles,name,'.$id.',id'],
        ]);
        $model = Role::query()->findOrFail($id);
        $data = $request->only(['name', 'display_name']);
        DB::transaction(function () use ($model, $data) {
            $model->update(['name' => $data['name'], 'guard_name' => static::GUARD_NAME]);
            $this->createSyslog('更新了一条角色记录', $data, $model);
        });
        return $this->succeed();
    }

    public function destroy(Request $request)
    {
        $request->validate(['ids' => ['required','array','max:'.static::QUERY_LIMIT]]);
        $ids = $request->get('ids');
        abort_if(in_array(1, $ids, true), ResponseEnum::ROLE_EXISTS_DELETE_ERROR);
        $list = Role::query()->select(['id'])->whereIn('id', $ids)->limit(static::QUERY_LIMIT)->withCount(['permissions', 'users'])->get();
        abort_if($list->isEmpty(), ResponseEnum::DELETE_NOT_EXIST_ERROR);
        DB::transaction(function () use ($list) {
            foreach ($list as $row) {
                $row->permissions_count > 0 && $row->permissions()->detach();
                $row->users_count > 0 && $row->users()->detach();
                $row->delete();
                $this->createSyslog('删除了一条角色记录', [], $row);
            }
        });
        return $this->succeed();
    }

    public function permission($id)
    {
        $role = Role::query()->with('permissions')->findOrFail($id);
        $menus = Menus::query()->select(['id', 'display_name', 'parent_id as parentId'])->get()->toArray();
        return $this->succeed([
            'list' => $menus,
            'checked' => $role->permissions->pluck('id'),
        ]);
    }

    public function assignPermission($id, Request $request)
    {
        $request->validate(['permissions' => ['required','array']]);
        $role = Role::query()->where('guard_name', static::GUARD_NAME)->findOrFail($id);
        $permissions = $request->get('permissions');
        $role->syncPermissions($permissions);
        $this->createSyslog('更新了角色的权限', $permissions, $role);
        return $this->succeed();
    }
}
